feat: add exact-cover allocation strategy#663
Conversation
…dation-engine-contract # Conflicts: # .github/workflows/security.yml
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c8e77d88c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new admin-only exact_cover_v1 allocation lane for batch/recurring recommendation constraints, while keeping weighted_v1 as the default for the standard recommendation workflow.
Changes:
- Introduces
RecommendationAllocationConfigand module settings for allocation strategy + solver limits. - Adds a new
/api/v1/recommendations/allocation/exact-coverendpoint with auditing + deterministic Algorithm X solver. - Adds shared exact-cover fixtures + contract gate checks and updates contract docs.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/check-recommendation-contract.sh | Extends the contract gate to validate exact-cover fixtures and key contract strings. |
| parkhub-server/src/api/recommendations.rs | Adds allocation config to engine config/stats and loads new module settings. |
| parkhub-server/src/api/recommendation_allocation.rs | New exact-cover solver + admin endpoint + audit trace generation + fixtures-based tests. |
| parkhub-server/src/api/modules/schemas.rs | Extends recommendations module schema with allocation strategy and solver limits. |
| parkhub-server/src/api/mod.rs | Wires the new allocation module and POST route. |
| docs/recommendation-engine-fixtures/exact_cover_v1.*.json | Adds parity fixtures to pin exact-cover semantics across implementations. |
| docs/recommendation-engine-contract.md | Documents exact-cover strategy semantics, config boundary, and audit trace requirements. |
… handler + legal-boundary fixtures - normalize_allocation_strategy(): trim + validate, fall back to weighted_v1 on unknown/whitespace input (fixes raw-string match that mis-handled padded values) - solve_exact_cover_allocation(): clone Database out of SharedState instead of holding the read guard across .await (check_admin_db / resolve_tenant_id_db helpers) - exact_cover_v1 fixtures gain legal_boundary (execution_allowed=false, attorney review required) + matching test assertions - unit test test_allocation_strategy_falls_back_to_weighted_v1
… tests, uuid schema, strategy rationale Thread 1 (P1 audit-persist failure): extract audit_persist_failure_response() pure helper so the compliance contract is directly testable; add audit_persist_failure_response_fails_closed_with_error_code asserting 500/AUDIT_TRACE_PERSIST_FAILED/success=false when audit trace cannot persist. Thread 5 (bounds clamping coverage): add exact_cover_limits_bounded_clamps_both_max_fields_into_caps to explicitly exercise ExactCoverLimits::bounded over-cap, below-floor, and in-range paths for both exact_cover_max_options and exact_cover_max_search_nodes. Thread 8 (recommendation_id uuid schema): restore #[schema(value_type = String, format = Uuid)] on SlotRecommendation. recommendation_id — removed by this PR; format:uuid confirmed present in committed OpenAPI JSON (utoipa default); restore for explicit contract stability and API surface consistency. Thread 9 (strategy String vs enum): keep String; add doc-comment on RecommendationAllocationConfig.strategy with forward-compat rationale (read_module_string + normalize_allocation_strategy graceful fallback; strict-deserializing enum breaks unknown-strategy-fallback contract). Threads 2/3/4/6/7 addressed in prior commit 9d60b11: effective_limits enforces module-config caps, database_from_shared_state drops RwLock before any await, audit_exact_cover_allocation takes &Database, tests use super::status_name, fixtures carry correct legal_boundary shape. LEFTHOOK=0: cargo fmt deferred to make ci (capacity-gated during swap spike; fmt is style-only and will be verified at gate time).
…ned (transitive via validator_derive) Added to osv-scanner.toml following existing pattern for unmaintained transitive build-time proc-macro crates with no fixed version. Mirrors deny.toml comment style.
…ned in deny.toml proc-macro-error2 2.0.1 is pulled transitively via validator_derive -> validator 0.20. The advisory marks the entire crate as unmaintained with no fixed version published; suppressing in deny.toml (parallel to the existing RUSTSEC-2024-0370 entry and the osv-scanner.toml entry added in the previous commit). cargo deny check advisories: 0 errors.
Adds the exact-cover allocation strategy lane for recommendation constraints while keeping weighted_v1 as the normal default.
Local Nido evidence: